package com.ruoyi.system.basicInformation.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.common.annotation.DataScope;
import com.ruoyi.common.core.domain.TreeSelect;
import com.ruoyi.common.core.domain.entity.TShipTree;
import com.ruoyi.common.exception.BaseException;
import com.ruoyi.common.exception.CustomException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.system.basicInformation.bo.AttachSaveOrEditBo;
import com.ruoyi.system.basicInformation.service.ITTerminalService;
import com.ruoyi.system.frontierEvent.bo.TAttachAddBo;
import com.ruoyi.system.frontierEvent.service.ITAttachService;
import com.ruoyi.system.frontierEvent.vo.TAttachVo;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.Page;
import com.ruoyi.system.basicInformation.bo.TShipAddBo;
import com.ruoyi.system.basicInformation.bo.TShipQueryBo;
import com.ruoyi.system.basicInformation.bo.TShipEditBo;
import com.ruoyi.system.basicInformation.domain.TShip;
import com.ruoyi.system.basicInformation.mapper.TShipMapper;
import com.ruoyi.system.basicInformation.vo.TShipVo;
import com.ruoyi.system.basicInformation.service.ITShipService;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 船舶信息Service业务层处理
 *
 * @author ruoyi
 * @date 2021-05-20
 */
@Service
public class TShipServiceImpl extends ServiceImpl<TShipMapper, TShip> implements ITShipService {

    @Autowired
    private ITAttachService iTAttachService;
    @Autowired
    private ITTerminalService itTerminalService;
    @Autowired
    private ITShipService itShipService;

    @Override
    public TShipVo queryById(Long id) {
        TShipVo tShipVo = this.baseMapper.selectById(id);
        List<TAttachVo> tAttachVoList = iTAttachService.selectByShipId(tShipVo.getId());
        List<AttachSaveOrEditBo> attachSaveOrEditBoList = new ArrayList<>();
        for (TAttachVo in : tAttachVoList) {
            AttachSaveOrEditBo attachSaveOrEditBo = new AttachSaveOrEditBo();
            attachSaveOrEditBo.setId(in.getFileId());
            attachSaveOrEditBo.setName(in.getFileName());

            attachSaveOrEditBoList.add(attachSaveOrEditBo);
        }
        tShipVo.setShowUmEvtAttchList(attachSaveOrEditBoList);
        return tShipVo;
    }

    @Override
    public List<TShipVo> queryList(TShipQueryBo bo) {
//        LambdaQueryWrapper<TShip> lqw = Wrappers.lambdaQuery();
//        lqw.like(StrUtil.isNotBlank(bo.getShipName()), TShip::getShipName, bo.getShipName());
//        lqw.like(StrUtil.isNotBlank(bo.getShipCode()), TShip::getShipCode, bo.getShipCode());
//        lqw.eq(StrUtil.isNotBlank(bo.getShipType()), TShip::getShipType, bo.getShipType());
//
//        if (StrUtil.isNotBlank(bo.getShipIds())) {
//            String[] ids = bo.getShipIds().split(",");
//            List<Integer> newIds = new ArrayList<>();
//            for (String i : ids) {
//                newIds.add(Integer.parseInt(i));
//            }
//            if (newIds.size() > 0)
//                lqw.notIn(TShip::getId, newIds);
//        }
//
//        return entity2Vo(this.list(lqw));
        List<TShipVo> tShipVoList = null;
        if (!SecurityUtils.getLoginUser().getUser().getUserType().equals("00")) {
            if (SecurityUtils.getLoginUser().getUser().getDept().getDeptId() != null) {
                bo.setDeptId(SecurityUtils.getLoginUser().getUser().getDept().getDeptId());
                tShipVoList = baseMapper.querypList(bo);
            } else return null;
        } else {
            tShipVoList = baseMapper.querypList(bo);
        }
//        List<TShipVo> tShipVoList = this.baseMapper.querypList(bo);
        if (tShipVoList != null) {
            for (TShipVo item :
                    tShipVoList) {
                List<TAttachVo> tAttachVoList = iTAttachService.selectByShipId(item.getId());

                List<AttachSaveOrEditBo> attachSaveOrEditBoList = new ArrayList<>();
                for (TAttachVo in : tAttachVoList) {
                    AttachSaveOrEditBo attachSaveOrEditBo = new AttachSaveOrEditBo();
                    attachSaveOrEditBo.setId(in.getFileId());
                    attachSaveOrEditBo.setName(in.getFileName());

                    attachSaveOrEditBoList.add(attachSaveOrEditBo);
                }

                item.setShowUmEvtAttchList(attachSaveOrEditBoList);
            }
        }

        return tShipVoList;
    }

    @Override
    public List<TShipVo> listShipPersonnelStatistics(TShipQueryBo bo) {
        return this.baseMapper.listShipPersonnelStatistics(bo);
    }

    @Override
    public List<TShipVo> listShipCurrentPoint(TShipQueryBo bo) {
        if (SecurityUtils.getLoginUser().getUser().getAreaId() != 1)
            bo.setAreaId(SecurityUtils.getLoginUser().getUser().getAreaId() > 0 ? SecurityUtils.getLoginUser().getUser().getAreaId() : 0);
        return this.baseMapper.listShipCurrentPoint(bo);
    }

    /**
     * 实体类转化成视图对象
     *
     * @param collection 实体类集合
     * @return
     */
    private List<TShipVo> entity2Vo(Collection<TShip> collection) {
        List<TShipVo> voList = collection.stream()
                .map(any -> BeanUtil.toBean(any, TShipVo.class))
                .collect(Collectors.toList());
        if (collection instanceof Page) {
            Page<TShip> page = (Page<TShip>) collection;
            Page<TShipVo> pageVo = new Page<>();
            BeanUtil.copyProperties(page, pageVo);
            pageVo.addAll(voList);
            voList = pageVo;
        }
        return voList;
    }

    /**
     * 新增保存用户信息
     *
     * @param user 用户信息
     * @return 结果
     */
    @Override
    @Transactional
    public int insertShip(TShip user) {
        // 新增用户信息
        int rows = baseMapper.insert(user);

        return rows;
    }

    @Override
    @DataScope(deptAlias = "d")
    public List<TreeSelect> selectShipList(TShipTree dept) {
        List<TShipTree> tShipTreeList = baseMapper.selectShipList(dept);

        return tShipTreeList.stream().map(TreeSelect::new).collect(Collectors.toList());
    }

    /**
     * 修改保存用户信息
     *
     * @param user 用户信息
     * @return 结果
     */
    @Override
    @Transactional
    public int updateShip(TShip user) {
        Long userId = user.getId();

        return baseMapper.updateById(user);
    }

    /**
     * 导入用户数据
     *
     * @param userList        APP用户数据列表
     * @param isUpdateSupport 是否更新支持，如果已存在，则进行更新数据
     * @param operName        操作用户
     * @return 结果
     */
    @Override
    public String importUser(List<TShip> userList, Boolean isUpdateSupport, String operName, String shipType) {
        if (Validator.isNull(userList) || userList.size() == 0) {
            throw new CustomException("导入船舶信息不能为空！");
        }
        int successNum = 0;
        Integer failureNum = 0;
        Integer validNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        String regexPhone = "^((13[0-9])|(14[5,7,9])|(15([0-3]|[5-9]))|(17[0,1,3,5,6,7,8])|(18[0-9])|(19[8|9])|(16[6]))\\d{8}$";
        String regexIdcard = "^[1-9]\\d{5}(18|19|([23]\\d))\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$";
        boolean s = true;
        //String password = configService.selectConfigByKey("sys.user.initPassword");
        for (TShip user : userList) {
            if (Validator.isEmpty(user.getShipName())) {
                failureNum++;
                String msg = "<br/>" + failureNum + "、有数据没有填写的船舶名称，导入失败;";
                failureMsg.append(msg);
            } else {
                validNum = importUserValid(failureMsg, user, regexIdcard, regexPhone);
                failureNum += validNum;
                s = validNum > 0 ? false : true;
                validNum = 0;
                if (s) {
                    try {
                        // 验证是否存在这个用户
                        TShip u = itShipService.getOne(new LambdaQueryWrapper<TShip>().eq(TShip::getShipName, user.getShipName()));
                        user.setShipType(shipType);
                        if (Validator.isNotNull(u)) {
                            if (isUpdateSupport) {
                                user.setUpdateBy(operName);
                                user.setId(u.getId());
                                this.updateShip(user);
                                successNum++;
                                successMsg.append("<br/>" + successNum + "、船舶名称 '" + user.getShipName() + "' 更新成功");
                            } else {
                                failureNum++;
                                failureMsg.append("<br/>" + failureNum + "、船舶名称 '" + user.getShipName() + "' 导入失败，已存在");
                            }
                        } else {
                            if (count(new LambdaQueryWrapper<TShip>().eq(TShip::getShipCode, user.getShipCode()).last("limit 1")) > 0) {
                                s = false;
                                failureNum++;
                                failureMsg.append("<br/>" + failureNum + "、船舶名称 " + user.getShipName() + " 的数据,船舶编码已存在;");
                            }
                            if (count(new LambdaQueryWrapper<TShip>().eq(TShip::getContactNumber, user.getContactNumber()).last("limit 1")) > 0) {
                                s = false;
                                failureNum++;
                                failureMsg.append("<br/>" + failureNum + "、船舶名称 " + user.getShipName() + " 的数据,的联系电话已存在;");
                            }
                            if (count(new LambdaQueryWrapper<TShip>().eq(TShip::getCertificateNumber, user.getCertificateNumber()).last("limit 1")) > 0) {
                                s = false;
                                failureNum++;
                                failureMsg.append("<br/>" + failureNum + "、船舶名称 " + user.getShipName() + " 的数据,所有人证件号已存在;");
                            }
                            if (s) {
                                user.setCreateBy(operName);
                                this.insertShip(user);
                                successNum++;
                                successMsg.append("<br/>" + successNum + "、船舶名称 '" + user.getShipName() + "' 导入成功");
                            }
                        }
                    } catch (Exception e) {
                        failureNum++;
                        String msg = "<br/>" + failureNum + "、船舶名称 '" + user.getShipName() + "' 导入失败：";
                        failureMsg.append(msg + e.getMessage());
                        log.error(msg, e);
                    }
                }
            }
        }
        if (failureNum > 0) {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new CustomException(failureMsg.toString());
        } else {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }

    private Integer importUserValid(StringBuilder failureMsg, TShip user, String regexIdcard, String regexPhone) {
        Integer failureNum = 0;
        if (Validator.isEmpty(user.getShipCode())) {
            failureNum++;
            failureMsg.append("<br/>" + failureNum + "、船舶名称 '" + user.getShipName() + "' 的船舶编码为空;");
        }
        if (Validator.isEmpty(user.getContactNumber())) {
            failureNum++;
            failureMsg.append("<br/>" + failureNum + "、船舶名称 '" + user.getShipName() + "' 的联系电话为空;");
        } else {
            Pattern p = Pattern.compile(regexPhone);
            Matcher m = p.matcher(user.getContactNumber());
            if (!m.matches()) {
                failureNum++;
                String msg = "<br/>" + failureNum + "、船舶名称 '" + user.getShipName() + "' ,的联系电话格式错误;";
                failureMsg.append(msg);
            }
        }
        if (Validator.isEmpty(user.getCertificateNumber())) {
            failureNum++;
            failureMsg.append("<br/>" + failureNum + "、船舶名称 '" + user.getShipName() + "' 的所有人证件号为空;");
        } else {
            Pattern p = Pattern.compile(regexIdcard);
            Matcher m = p.matcher(user.getCertificateNumber());
            if (!m.matches()) {
                failureNum++;
                String msg = "<br/>" + failureNum + "、船舶名称 '" + user.getShipName() + "' ,的所有人证件号格式错误;";
                failureMsg.append(msg);
            }
        }
        return failureNum;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean insertByAddBo(TShipAddBo bo) {
        boolean save = false;
        TShip add = BeanUtil.toBean(bo, TShip.class);
        validEntityBeforeSave(add, 1);
        try {
            save = this.save(add);
            if (save) {
                //bo = BeanUtil.toBean(add, TShipAddBo.class);
                itTerminalService.updateTerminalByObjId(bo.getTerminalId(), add.getId());
                if (bo.getShowUmEvtAttchList() != null) {
                    //新增附件记录
                    for (int i = 0; i < bo.getShowUmEvtAttchList().size(); i++) {
                        TAttachAddBo tAttachAddBo = new TAttachAddBo();
                        tAttachAddBo.setShipId(add.getId());
                        tAttachAddBo.setEvtActType(new Long(1));
                        tAttachAddBo.setFileId(bo.getShowUmEvtAttchList().get(i).getId());
                        tAttachAddBo.setFileName(bo.getShowUmEvtAttchList().get(i).getId() + bo.getShowUmEvtAttchList().get(i).getName().substring(bo.getShowUmEvtAttchList().get(i).getName().indexOf('.')));
                        save = iTAttachService.insertByAddBo(tAttachAddBo);
                    }
                }
            }
        } catch (
                Exception e) {
            e.printStackTrace();
            throw new BaseException("新增船舶信息失败");
        }
        return save;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateByEditBo(TShipEditBo bo) {
        boolean save = false;
        TShip update = BeanUtil.toBean(bo, TShip.class);
        validEntityBeforeSave(update, 2);
        try {
            save = this.updateById(update);
            if (save) {
                if (bo.getNewUmEvtAttachList() != null) {
                    //新增附件记录
                    for (int i = 0; i < bo.getNewUmEvtAttachList().size(); i++) {
                        TAttachAddBo tAttachAddBo = new TAttachAddBo();
                        tAttachAddBo.setShipId(bo.getId());
                        tAttachAddBo.setEvtActType(new Long(1));
                        tAttachAddBo.setFileId(bo.getNewUmEvtAttachList().get(i).getId());
                        tAttachAddBo.setFileName(bo.getNewUmEvtAttachList().get(i).getId() + bo.getNewUmEvtAttachList().get(i).getName().substring(bo.getNewUmEvtAttachList().get(i).getName().indexOf('.')));
                        save = iTAttachService.insertByAddBo(tAttachAddBo);
                    }
                    if (save) {
                        //删除附件记录
                        for (int i = 0; i < bo.getRemoveUmEvtAttachList().size(); i++) {
                            save = iTAttachService.deleteByFileId(bo.getRemoveUmEvtAttachList().get(i).getId());
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new BaseException("修改船舶信息失败");
        }
        return save;
    }

    /**
     * 保存前的数据校验
     *
     * @param entity 实体类数据
     */
    private void validEntityBeforeSave(TShip entity, int type) {
        QueryWrapper<TShip> lqw = new QueryWrapper<>();
        lqw.lambda().eq(TShip::getShipName, entity.getShipName());
        TShip tShip = this.baseMapper.selectOne(lqw);
        if (Validator.isNotNull(tShip)) {
            //type为1时为新增
            if (type == 1) {
                //TODO 做一些数据校验,如唯一约束
                throw new BaseException("此船名已存在！");
            } else {
                if (entity.getId().longValue() != tShip.getId().longValue()) {
                    //TODO 做一些数据校验,如唯一约束
                    throw new BaseException("此船名已存在！");
                }
            }
        }
        QueryWrapper<TShip> lqw1 = new QueryWrapper<>();
        lqw1.lambda().eq(TShip::getShipCode, entity.getShipCode());
        TShip tShip1 = this.baseMapper.selectOne(lqw1);
        if (Validator.isNotNull(tShip1)) {
            //type为1时为新增
            if (type == 1) {
                //TODO 做一些数据校验,如唯一约束
                throw new BaseException("此船舶编码已存在！");
            } else {
                if (entity.getId().longValue() != tShip1.getId().longValue()) {
                    //TODO 做一些数据校验,如唯一约束
                    throw new BaseException("此船舶编码已存在！");
                }
            }
        }
    }

    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return this.removeByIds(ids);
    }

//    public static void main(String[] args) {
//
//        AtomicInteger number = new AtomicInteger(0);
//
//        String msg = "";
//        System.out.println(number.get());
//        msg = preNum(number);
//        System.out.println(number.get());
//    }
//
//    private static String preNum(AtomicInteger number) {
//        number.getAndIncrement();
//        return "aaa";
//    }
//
//    @Data
//    static
//    class DemoNum {
//        int num;
//    }
}
